package com.hzd.service;

import ablaze.framework.api.result.ExecuteResult;
import ablaze.framework.config.SystemConfig;
import ablaze.framework.page.PageInfo;
import ablaze.framework.security.verifycode.VerifyCodeService;
import ablaze.framework.service.BaseService;
import ablaze.framework.utils.BigDecimalUtils;
import ablaze.framework.utils.ValidateUtils;
import com.avaje.ebean.ExpressionList;
import com.avaje.ebean.Query;
import com.hzd.condition.TenantCondition;
import com.hzd.entity.Tenant;
import com.hzd.sdk.api.SnsAPI;
import com.hzd.sdk.bean.SnsToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;

/**
 * @author Kent
 * @date 2015/8/17.
 */
@Component
@Transactional
public class RentService extends BaseService {

    private static final String APPID_KEY = "wx.appid";
    private static final String SECRET_KEY = "wx.secret";


    @Autowired
    private VerifyCodeService verifyCodeService;

    @Autowired
    private ActivityService activityService;


    /**
     * 获取微信用户openid
     *
     * @param code
     * @return
     */
    public String getOpenId(String code) {

        if (isEmpty(code)) {
            return null;
        }

        SnsToken snsToken = SnsAPI.oauth2AccessToken(SystemConfig.getString(APPID_KEY), SystemConfig.getString(SECRET_KEY), code);

        return snsToken.getOpenid();
    }

    public List<Tenant> findAll(TenantCondition tenant) {

        Query<Tenant> query = find(Tenant.class);

        if (ValidateUtils.isEmpty(tenant)) {
            return query.findList();
        }

        return query.where()
                .contains("name", tenant.getName())
                .eq("idNo", tenant.getIdNo())
                .eq("mobileNo", tenant.getMobileNo())
                .contains("address", tenant.getAddress())
                .eq("rentDate", tenant.getRentDate())
                .eq("referrer", tenant.getReferrer())
                .findList();
    }


    /**
     * 租+申请分页查询
     *
     * @param pageIndex
     * @param pageSize
     * @param condition
     * @return
     */
    public PageInfo findApplyPagedList(Integer pageIndex, Integer pageSize, TenantCondition condition) {


        ExpressionList expressionList =
                findUseable(Tenant.class)
                        .where()
                        .contains("name", condition.getName())
                        .eq("idNo", condition.getIdNo())
                        .eq("mobileNo", condition.getMobileNo())
                        .contains("address", condition.getAddress())
                        .eq("rentDate", condition.getRentDate())
                        .eq("referrer", condition.getReferrer())
                        .eq("paymentMethod", condition.getPaymentMethod());

        if (isNotEmpty(condition.getApplyDate())) {
            expressionList = expressionList.like("createtime", condition.getApplyDate() + "%");
        }

        Query query = expressionList.orderBy("createtime desc");

        return findPagedList(
                pageIndex,
                pageSize,
                query
        );
    }

    /**
     * 保存更新
     *
     * @param tenant
     * @return
     */
    public ExecuteResult saveOrUpdate(Tenant tenant) {

        if (ValidateUtils.isEmpty(tenant)) {
            return failParamNull();
        }

        if (isEmpty(tenant.getOpenid())) {
            return failParamNull("请在微信浏览器中打开");
        }

        if (entityValidate(tenant).fail()) {
            return failParamNull(entityValidate(tenant).errorString());
        }

        //手机号是否已注册
        if (mobileNoDuplited(tenant.getId(), tenant.getMobileNo())) {
            return failDataDuplicated("手机号已注册");
        }

        if (!verifyCodeService.validate(tenant.getMobileNo(), tenant.getVerifyCode())) {
            return failParamInvalidate("验证码不正确");
        }

        //保存申请
        store(tenant);

        //处理活动链接跳转过来的申请
        if (tenant.isFromAcivityFlag()) {
            return activityService.claimBond(tenant.getOpenid());
        }
        //普通方式打开申请
        return success(tenant);
    }


    /**
     * 发送验证码
     *
     * @param mobile
     * @return
     */
    public ExecuteResult sendVerifyCode(String mobile) {

        if (isEmpty(mobile)) {
            return failParamNull();
        }

        verifyCodeService.send(mobile, "您注册的互助贷验证码为${verifyCode}，请于5分钟内正确输入验证码");

        return success();
    }

    /**
     * 计算代垫租金以及服务费
     *
     * @param id
     * @return
     */
    public Map operRentAmount(String id) {

        if (isEmpty(id)) {
            return toMap();
        }

        Tenant tenant = findUseableById(Tenant.class, id);

        if (isEmpty(tenant)) {
            return toMap();
        }

        //收入-支出-1800
        BigDecimal rent = tenant.getIncome()
                .subtract(tenant.getExpense())
                .subtract(new BigDecimal("1800"));

        //小于0直接返回结果0
        if (BigDecimalUtils.compareTo(rent, new BigDecimal(0)) < 0) {
            return RentResultWrapper(new BigDecimal("0.0"));
        }

        BigDecimal income = tenant.getIncome().multiply(new BigDecimal("0.35"));

        //收入-支出-1800和收入35%两者返回小的那只
        if (BigDecimalUtils.compareTo(rent,income) < 0){
            return RentResultWrapper(rent);
        }

        return  RentResultWrapper(income);
    }

    /**
     * 组装返回结果
     *
     * @param rent
     * @return
     */
    private Map RentResultWrapper(BigDecimal rent) {
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        BigDecimal totalAmount = rent.multiply(new BigDecimal(3));
        return toMap("amount", decimalFormat.format(rent),
                "totalAmount", decimalFormat.format(totalAmount),
                "fee", decimalFormat.format(totalAmount.multiply(new BigDecimal("0.02"))));
    }

    //----------------------------私有方法区-------------------------------

    private boolean mobileNoDuplited(String id, String mobileNo) {

        return find(Tenant.class)
                .where()
                .ne("id", id)
                .eq("mobileNo", mobileNo)
                .findRowCount() > 0;
    }
}
